package top.zhangjianyong.blog.utils;

import cn.hutool.core.util.StrUtil;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Optional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.zhangjianyong.blog.constant.RequestHeaderKey;

/**
 * @author zhangjianyong
 * @since 2024/8/27 上午10:03
 */
public class RequestUtil {

  private static HttpServletRequest getHttpServletRequest() {
    RequestAttributes ra = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributes sra = (ServletRequestAttributes) ra;
    if (sra != null) {
      return sra.getRequest();
    }
    return null;
  }

  public static String getMethod() {
    return Optional.ofNullable(getHttpServletRequest())
        .map(HttpServletRequest::getMethod)
        .orElse("");
  }

  public static String getUri() {
    return Optional.ofNullable(getHttpServletRequest())
        .map(HttpServletRequest::getRequestURI)
        .orElse("");
  }

  public static String getVisitUUID() {
    return Optional.ofNullable(getHttpServletRequest())
        .map(r -> r.getHeader(RequestHeaderKey.VISITOR_UUID))
        .orElse(null);
  }

  public static String getClientUserAgent() {
    return Optional.ofNullable(getHttpServletRequest())
        .map(request -> request.getHeader(RequestHeaderKey.USER_AGENT))
        .orElse("");
  }

  public static String getClientIP() {
    return Optional.ofNullable(getHttpServletRequest())
        .map(
            request -> {
              String ip = request.getHeader("x-forwarded-for");
              if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
              }
              if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
              }
              if (StrUtil.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
              }
              return ip;
            })
        .orElse("");
  }
}
